Introduction to the ZYNQ 7000 Boot Process

System Boot Overview

The ZYNQ-7000 is an SoC based on the ARM Cortex-A9 + FPGA architecture. Its boot process is hardware-driven (by the PS) and completes the system startup and programmable logic configuration in stages. The boot process for the ZYNQ 7000 SoC is a multi-stage, highly configurable procedure involving complex interactions between automatic hardware loading and software control. This article will provide a detailed analysis of the entire process, from power-on to the loading of the operating system.

Hardware Initialization Stage

Power-On and Hardware Reset

Power Supply and Clock Tree Initialization

POR (Power-On Reset) Sequence

Clock Network Configuration

Boot Mode Detection

The boot mode is determined by the MIO[5:2] pins:

MIO[5:2]Boot ModeClock FrequencyData Width
0000JTAG--
0010NAND33MHz8-bit
0011NOR50MHz16-bit
0101QSPI100MHz4-bit
0110SD50MHz4-bit

Note: The mode pins are sampled and latched on the rising edge of POR_B

BootROM Stage (Stage-0)

BootROM

The BootROM code is the first software to execute on a Zynq device after power-on or reset. It starts execution from address 0xFFFF_0000. The BootROM is not accessible to the user. The BootROM code is stored in the on-chip ROM, hence the name BootROM. Because the ZYNQ contains 256K of RAM and 128K of ROM, the BootROM code can be permanently stored in the ROM and will not be lost on power-off. Typically, the internal ROM of a chip is NOR Flash. A key feature of NOR Flash is eXecute In Place (XIP), which allows applications to run directly from the Flash memory without needing to be loaded into the system RAM. It is ROM embedded in the chip and cannot be modified.

The BootROM code performs the following functions:

BootROM code execution flow for SD card boot mode:

  1. Initializes the MIO pins, primarily configuring the physical characteristic configuration registers for the MIO pins. The key step is multiplexing MIO40~MIO45 to function as the CLK/CMD/DATA pins for the SD0 peripheral.

  2. Initializes the SD card peripheral and its driver, enabling SD card read/write operations.

  3. Tests SD card read/write functionality.

  4. Reads the BOOT.BIN file from the SD card's file system and parses the BootROM header. The BOOT.BIN file is preceded by a header section, which is organized in a specific format. This header contains information such as the FSBL's load address, size, and its offset within the BOOT.BIN file. The BootROM code is capable of parsing this header.

  5. After obtaining the FSBL code's size, offset, and load address, the BootROM code copies the FSBL code from the BOOT.BIN file into RAM and then jumps to the FSBL's execution address to start it.

At this point, the BootROM has successfully launched the FSBL code.

QSPI Boot Mode Flow

The execution flow of the BootROM code in QSPI boot mode is as follows:

  1. Initializes the MIO pins, multiplexing the relevant MIO pins to serve the functions required by the QSPI peripheral.

  2. Initializes the QSPI peripheral and its driver for the QSPI Flash device, enabling QSPI read/write operations.

  3. Tests QSPI read/write functionality.

  4. Reads the BOOT.BIN file from the QSPI storage medium and parses the Boot ROM header.

  5. After obtaining the FSBL code's size, offset, and load address, the BootROM code copies the FSBL code from the BOOT.BIN file into RAM and then jumps to the FSBL's execution address to start it.

Unlike the file system search method used for SD cards, in QSPI boot mode, the BootROM code first looks for the BOOT.BIN file at address 0x000000 of the QSPI. If it's not found, it proceeds to the next address, 0x008000. If it's still not found, it jumps to the next address, 0x10000. However, the search range cannot exceed the first 16MB of the QSPI address space.

BOOT.BIN File Structure

BOOT.BIN is the core boot image file for the ZYNQ 7000 series SoC. (A boot image is a packaged file containing multiple programs or data required for system startup, typically a binary file used to guide the system through the entire process from power-on to operating system launch. In Zynq, the boot image is usually the BOOT.BIN file. BOOT.BIN is the core file for the entire system startup and must be placed at the beginning of the Zynq boot device. It is read and executed by Zynq's ROM boot code from QSPI, SD card, or NAND.) It is generated by the Bootgen tool based on a .bif file and contains all the components needed for the complete boot chain. For example:

In the example above:

Partition OrderContentPurpose
1fsbl.elfFirst-stage bootloader, initializes hardware and DDR
2system.bitConfigures the PL (FPGA part)
3u-boot.elfSecond-stage bootloader, starts Linux or other applications

Overall File Structure

Boot Header Details

The BOOT.BIN header is a data section at the beginning of the BOOT.BIN file, organized in a specific format that can be parsed by the BootROM code. The BootROM reads the Boot Header from the boot image to obtain information about the image, such as:

The Boot Header must exist and be correctly formatted. Otherwise, the BootROM will not load the FSBL.

VeryCapture_20250606155931

VeryCapture_20250606155955

In the BOOT.bin file, the address range from 0 to 0x8FF can be divided into 17 parts, each with a specific meaning.

  1. 0x000: Interrupt vector table.

  2. 0x020: Fixed value 0xaa995566 (little-endian).

  3. 0x024: Fixed value 0x584c4e58 ASCII: XLNX.

  4. 0x028: If the value is 0xa5c3c5a3 or 0x3a5c3c5a, the image is encrypted.

  5. 0x02C: BootROM header version number, can be ignored.

  6. 0x030: This parameter contains the number of bytes from the start of the valid BootROM header to the location of the FSBL/user code image, which is the address offset of the FSBL/user code. This offset must be greater than or equal to 0x8C0.

  7. 0x034: Records the length of the FSBL, used to guide the BootROM code in copying the FSBL.

  8. 0x038: The load address, specifying where to copy the FSBL into OCM (usually 0x0). It guides the BootROM code on where to copy the FSBL in RAM.

  9. 0x03C: The execution address of the FSBL in OCM (usually defined as 0x0). It guides the BootROM code on which RAM address to jump to for execution.

  10. 0x040: Records the length of the FSBL.

  11. 0x044: Fixed value 0x01.

  12. 0x048: Checksum (Calculated by summing the data between 0x020 and 0x047 as 32-bit words and then taking the bitwise NOT. If the sum exceeds 32 bits, only the lower 32 bits are used for the NOT operation).

  13. 0x04C-0x097: User-defined area for FSBL/user code. Can be filled with zeros if not needed.

  14. 0x098: Offset to the image header table.

  15. 0x09C: Location of the partition header table.

  16. 0x0A0-0x89F: Parameters for register initialization.

17.0x8C0: The FSBL and user code must be located at or after this address.

VeryCapture_20250606162018

BootROM Code Execution

Initial PC Pointer

FSBL Stage (Stage-1)

Initialization Process

PS Configuration Sequence:

  1. Initialize DDR controller

  2. Configure MIO pin multiplexing

  3. Set system clocks

  4. Enable interrupt controller

Core Role of FSBL

FSBL is the First Stage Bootloader in the Zynq boot process, directly loaded and executed by the BootROM. Its main functions include:

How Does FSBL Load an Application Project?

Scenario 1: Bare-metal Application (Standalone)

Interaction Between FSBL and Application

PL Configuration

Bitstream Loading Process:

Configuration Time Estimation:

Bitstream SizeConfiguration Time (100MHz)
1MB80ms
5MB400ms
10MB800ms

How to Find U-Boot and Bitstream via BOOT.BIN

The BOOT.BIN file contains the FSBL image, the u-boot image, and the bitstream file.

The BootROM code needs to find the FSBL by parsing the BOOT.BIN header information. The BootROM code then starts the FSBL.

After the FSBL code runs, it is responsible for finding the U-Boot image and the bitstream file from the BOOT.BIN file, then loading the bitstream file to the ZYNQ PL side, and finally starting U-Boot.

This involves three data tables:

Image Header Table

There is only one image header table. The partition header table and image header appear in pairs. The number of images contained in the BOOT.BIN file determines the number of partition header table and image header pairs.

VeryCapture_20250609091441

Image Header

VeryCapture_20250609091458

Partition Header Table

VeryCapture_20250609091702

VeryCapture_20250609091715

Hierarchical Relationship and Function of Three Key Data Structures: Image Header Table, Partition Header Table, and Image Header


Hierarchical Structure

VeryCapture_20250609102303


Detailed Explanation

Image Header
Image Header Table
Partition Header Table

Workflow

BootROM reads the Image Header to verify the integrity of the image.

FSBL parses the Image Header Table to locate all partitions.

For each partition:

In-depth Analysis of FSBL (First Stage Boot Loader) Source Code

FSBL Overall Architecture and Boot Process

FSBL is the first user-programmable code executed after the ZYNQ platform powers on. It is primarily responsible for hardware initialization and loading the next-stage bootloader. Its core architecture is as follows:

image-20250909110824954

Core Code Module Analysis

Hardware Initialization (main() function)
Boot Image Loading (LoadBootImage())

Key Data Structures

Partition Header Structure (PartHeader)
Attribute Word Bitmasks

Security Mechanism Implementation

Secure Boot Process

image-20250909112532534

Key Security Functions

Stage-2 Boot

U-Boot Loading

Example Memory Layout:

U-Boot Environment Variables:

Secure Boot Implementation

Authentication Process

RSA Verification Steps:

image-20250909112856529

AES Decryption Process:

Advanced Features

Multiboot

Register Configuration:

Example Flash Layout:

Debugging and Optimization

Common Issues Troubleshooting

Boot Failure Diagnostics:

SymptomPossible CauseSolution
Stuck at BootROMBoot device detection failedCheck MIO pin configuration
FSBL fails to loadInsufficient OCM spaceOptimize FSBL size to <192KB
PL configuration timeoutPCAP interface clock not enabledCheck SLCR register configuration

Performance Optimization Tips:

Appendix

Key Register Reference

SLCR Registers:

DevCfg Registers:

Official Documentation Reference